package microcredit.gui.util;

import java.awt.Component;
import java.awt.event.ActionEvent;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JTextField;

import microcredit.gui.base.BaseAction;
import microcredit.gui.selector.AbstractButtonPanel;
import microcredit.gui.selector.IConvertable;
import microcredit.gui.selector.IFilterable;
import microcredit.gui.selector.ILoadable;
import microcredit.gui.selector.IOpenable;
import microcredit.gui.selector.ISelectable;
import microcredit.gui.selector.SelectorPanel;
import microcredit.gui.selector.SelectorPanel.SelectorDialog;
import microcredit.gui.table.BeanTable.SelectionMode;
import net.miginfocom.swing.MigLayout;

public class ElementEditorField<E> extends AbstractButtonPanel {
	
	private static final long serialVersionUID = 1L;
	
	private JTextField textField;
	private JButton btnSelect;
	private JButton btnDelete;
	
//	private final IOpenable<E> openable;
	private final IConvertable<E> convertable;
	private final ILoadable<E> loadable;
	private final ISelectable<E> selectable;
	private Class<E> elementClass;
	private E element;
	private final DeleteAction deleteAction;
	private final SelectAction selectAction;
	
	public ElementEditorField(Class<E> elementClass, E element, ILoadable<E> loadable, IOpenable<E> openable, IConvertable<E> convertable, ISelectable<E> selectable) {
		this.elementClass = elementClass;
		this.loadable = loadable;
		this.convertable = convertable;
//		this.openable = openable;
		this.selectable = selectable;
		this.deleteAction = new DeleteAction(this);
		this.selectAction = new SelectAction(this);
		addAction(deleteAction);
		addAction(selectAction);
		init();
		setElement(element);
	}
	
	@Override
	protected void initUI() {
	}
	
	public void setEditable(boolean editable) {
		selectAction.setEnabled(editable);
		deleteAction.setEnabled(editable);
	}
	
	public void setElement(E element) {
		this.element = element;
		if (convertable != null && element != null) {
			getTextField().setText(convertable.toString(element));
		}
		if (element == null) {
			getTextField().setText("<< please select >>");
		}
		updateState();
	}
	
	public E getElement() {
		return element;
	}
	
	protected void init() {
		removeAll();
		
		setLayout(new MigLayout("", "0[grow 1, fill]0", "0[grow, fill]0"));
		add(getTextField(), "cell 0 0, growx");
		add(getBtnDelete(), "cell 0 0");
		add(getBtnSelect(), "cell 0 0");
	}
	
	private JTextField getTextField() {
		if (textField == null) {
			textField = new JTextField();
			textField.setEditable(false);
			textField.setColumns(10);
		}
		return textField;
	}
	
	private JButton getBtnDelete() {
		if (btnDelete == null) {
			btnDelete = new JButton(deleteAction);
			btnDelete.setIcon(new ImageIcon(ElementEditorField.class.getResource("/microcredit/icons/x16/delete2.png")));
		}
		return btnDelete;
	}
	private JButton getBtnSelect() {
		if (btnSelect == null) {
			btnSelect = new JButton(selectAction);
			btnSelect.setIcon(new ImageIcon(ElementEditorField.class.getResource("/microcredit/icons/x16/arrow_down_blue.png")));
		}
		return btnSelect;
	}
	
	private class DeleteAction extends BaseAction {
		private static final long serialVersionUID = 1L;
		public DeleteAction(Component parent) {
			super(parent);
		}
		@Override
		public void perform(ActionEvent e) throws Throwable {
			setElement(null);
		}
		@Override
		public void updateState() throws Throwable {
			setEnabled(element != null);
		}
	}
	
	private class SelectAction extends BaseAction {
		private static final long serialVersionUID = 1L;
		public SelectAction(Component parent) {
			super(parent);
		}
		@Override
		public void perform(ActionEvent e) throws Throwable {
			SelectorDialog<E> dialog  = SelectorPanel.createDialog(ElementEditorField.this, "Select member", elementClass, loadable, null, null, null, selectable, null, (IFilterable<E>)selectable, null);
			dialog.getSelectorPanel().setSelectionMode(SelectionMode.SINGLE);
			dialog.getSelectorPanel().setSelectedElement(getElement());
			dialog.setVisible(true);
			if (dialog.getSelectedElement() != null) {
				setElement(dialog.getSelectedElement());
			}
		}
	}
}
